﻿// Copyright (c) 2025 .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

#if NETFX_CORE
using Windows.UI.Xaml;
using Windows.UI.Xaml.Automation.Peers;
using Windows.UI.Xaml.Automation.Provider;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Markup;
#else
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
#endif

namespace ReactiveUI.Tests.Xaml;

/// <summary>
/// Tests for XAML and commands.
/// </summary>
[TestFixture]
[Apartment(ApartmentState.STA)]
public class XamlViewCommandTests
{
    /// <summary>
    /// Test that event binder binds to explicit inherited event.
    /// </summary>
    [Test]
    [Apartment(ApartmentState.STA)]
    public void EventBinderBindsToExplicitInheritedEvent()
    {
        var fixture = new FakeView();
        fixture.BindCommand(fixture!.ViewModel, static x => x!.Cmd, static x => x.TheTextBox, "MouseDown");
    }

    /// <summary>
    /// Test that event binder binds to implicit event.
    /// </summary>
    [Test]
    [Apartment(ApartmentState.STA)]
    public void EventBinderBindsToImplicitEvent()
    {
        var input = new Button();
        var fixture = new CreatesCommandBindingViaEvent();
        var cmd = ReactiveCommand.Create<int>(_ => { });

        Assert.That(fixture.GetAffinityForObject(input.GetType(), false), Is.GreaterThan(0));

        var invokeCount = 0;
        cmd.Subscribe(_ => ++invokeCount);

        var disp = fixture.BindCommandToObject(cmd, input, Observable.Return((object)5));
        using (Assert.EnterMultipleScope())
        {
            Assert.That(disp, Is.Not.Null);
            Assert.That(invokeCount, Is.Zero);
        }

        var automationPeer = new ButtonAutomationPeer(input);
        var invoker = (IInvokeProvider)automationPeer.GetPattern(PatternInterface.Invoke);

        invoker.Invoke();
        DispatcherUtilities.DoEvents();
        Assert.That(invokeCount, Is.EqualTo(1));

        disp?.Dispose();
        invoker.Invoke();
        Assert.That(invokeCount, Is.EqualTo(1));
    }
}
